/*****************************************************************
Mix3D WebGL Game Engine
Copyright (c) fantasy ( fantasy.x2x@gmail.com )
Listens:
Distributed under the Boost Software License, Version 1.0.
http://www.boost.org/LICENSE_1_0.txt
 ****************************************************************/
/**
 * @Desc    : math
 * @Author  : fantasy(fantasy.x2x@gmail.com)
 */
//////////////////////////////////////////////////////////////////
if(typeof(Mix3D) === 'undefined')
{
  Mix3D = {};
};

(function(Mix3D){
//////////////////////////////////////////////////////////////////
Mix3D.Math = Mix3D.Math || {};

/**
 * @desc : const
 **/
Mix3D.Math.Epsilon              = 0.0001;
Mix3D.Math.InvEpsilon           = 0.00000000000001;
Mix3D.Math.ZeroTolerance        = 0.00000001;
Mix3D.Math.PI	                  = 4.0*Math.atan(1.0);//3.14159265358979323846264338327950288419716939937511;
Mix3D.Math.TWO_PI	              = 2.0*Mix3D.Math.PI;
Mix3D.Math.HALF_PI							= (Mix3D.Math.PI*0.5);
Mix3D.Math.QUAT_PI						  = (Mix3D.Math.PI*0.25);
Mix3D.Math.EIGHTH_PI						= (Mix3D.Math.PI*0.125);
Mix3D.Math.PI_SQ					      = (9.86960440108935861883449099987615113531369940724079);
Mix3D.Math.INV_PI   						= 1.0/Mix3D.Math.PI;
Mix3D.Math.INV_TWO_PI           = 1.0/Mix3D.Math.TWO_PI;
Mix3D.Math.DEG_TO_RAD					  = (Mix3D.Math.PI/180.0);
Mix3D.Math.RAD_TO_DEG						= (180.0/Mix3D.Math.PI);
Mix3D.Math.LN_2                 = Math.log(2.0);
Mix3D.Math.LN_10                = Math.log(10.0);
Mix3D.Math.INV_LN_2             = 1.0/Mix3D.Math.LN_2;
Mix3D.Math.INV_LN_10            = 1.0/Mix3D.Math.LN_10;
Mix3D.Math.GRAVITY_CONSTANT			  = 9.81;
Mix3D.Math.MAX_VALUE            = Number.MAX_VALUE;
Mix3D.Math.Min_Value            = Number.MIN_VALUE;
Mix3D.Math.POS_INF              = Number.POSITIVE_INFINITY;
Mix3D.Math.NEG_INF              = Number.NEGATIVE_INFINITY;
/**
 * @desc : sign
 **/
Mix3D.Math.sign = function(s)
{
  return (s>0)?1:( (s<0)?-1:0 );
};

Mix3D.Math.Min = function( a, b )
{
  return a<b?a:b;
};

Mix3D.Math.Max = function( a, b )
{
  return a>b?a:b;
};

Mix3D.Math.Min3 = function( a, b, c )
{
  return Mix3D.Math.Min(a, Mix3D.Math.Min(b,c));
};

Mix3D.Math.Max3 = function( a, b, c )
{
  return Mix3D.Math.Max(a, Mix3D.Math.Max(b,c));
};


/**
 * @desc : radian to degree
 **/
Mix3D.Math.RadToDeg = function( radian )
{
  return radian*Mix3D.Math.RAD_TO_DEG;
};

/**
 * @desc : degree to radian
 **/
Mix3D.Math.DegToRad = function( degree )
{
  return degree*Mix3D.Math.DEG_TO_RAD;
};


/**
 * @desc : clamp value to range<minVal, maxVal>
 **/
Mix3D.Math.clamp = function(val, minVal, maxVal)
{
  return ( val < minVal ) ? minVal : ( ( val > maxVal ) ? maxVal : val ); 
};

/**
 * @desc : linear mapping from range<a1,a2> to range<b1,b2>
 **/
Mix3D.Math.mapLinear = function( val, a1, a2, b1, b2)
{
  return (( val - a1 ) / ( a2 - a1 ))*( b2 - b1 ) + b1;
};

/**
 * @desc : random float from< 0, 1>, with 16 bits of randomness
 **/
Mix3D.Math.random16 = function()
{
  return ( 65280 * Math.random() + 255 * Math.random() ) / 65535;
};
/**
 * @desc : random int from< low, high>
 **/
Mix3D.Math.randomRangeInt = function( low, high )
{
  return low + Math.floor( Math.random() * ( high - low + 1 ) );
};
/**
 * @desc : random float from< low, high>
 **/
Mix3D.Math.randomRangeFloat = function( low, high )
{
  return low + Math.random() * ( high - low );
};
/**
 * @desc : random float from< -range/2, range/2>
 **/
Mix3D.Math.randomFloatSpread = function( range )
{
  return range * ( 0.5 - Math.random() );
};

/**
 * @desc : value is power 2 ?
 **/
Mix3D.Math.isPower2 = function ( v ) 
{
	return ( v & ( v - 1 ) ) === 0;
};
//////////////////////////////////////////////////////////////////
})(Mix3D); //endof function(Mix3D)